/*
 * Copyright (C) 2011-2021 Intel Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *   * Neither the name of Intel Corporation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/**
 * File: td_ql_wrapper.h
 *
 * Description: API definitions for TD quote library
 *
 */
#ifndef _TD_QL_WRAPPER_H_
#define _TD_QL_WRAPPER_H_
#include <stddef.h>
#include <stdbool.h>
#include "sgx_quote_4.h"

#define TEE_ATT_MK_ERROR(x)              (0x00011000|(x))

/** Possible errors generated by the quote interface. */
typedef enum _tee_att_error_t {
    TEE_ATT_SUCCESS = 0x0000,                                         ///< Success
    TEE_ATT_ERROR_MIN = TEE_ATT_MK_ERROR(0x0001),                      ///< Indicate min error to allow better translation.
    TEE_ATT_ERROR_UNEXPECTED = TEE_ATT_MK_ERROR(0x0001),               ///< Unexpected error
    TEE_ATT_ERROR_INVALID_PARAMETER = TEE_ATT_MK_ERROR(0x0002),        ///< The parameter is incorrect
    TEE_ATT_ERROR_OUT_OF_MEMORY = TEE_ATT_MK_ERROR(0x0003),            ///< Not enough memory is available to complete this operation
    TEE_ATT_ERROR_ECDSA_ID_MISMATCH = TEE_ATT_MK_ERROR(0x0004),        ///< Expected ECDSA_ID does not match the value stored in the ECDSA Blob
    TEE_ATT_PATHNAME_BUFFER_OVERFLOW_ERROR = TEE_ATT_MK_ERROR(0x0005), ///< The ECDSA blob pathname is too large
    TEE_ATT_FILE_ACCESS_ERROR = TEE_ATT_MK_ERROR(0x0006),              ///< Error accessing ECDSA blob
    TEE_ATT_ERROR_STORED_KEY = TEE_ATT_MK_ERROR(0x0007),               ///< Cached ECDSA key is invalid
    TEE_ATT_ERROR_PUB_KEY_ID_MISMATCH = TEE_ATT_MK_ERROR(0x0008),      ///< Cached ECDSA key does not match requested key
    TEE_ATT_ERROR_INVALID_PCE_SIG_SCHEME = TEE_ATT_MK_ERROR(0x0009),   ///< PCE use the incorrect signature scheme
    TEE_ATT_ATT_KEY_BLOB_ERROR = TEE_ATT_MK_ERROR(0x000a),             ///< There is a problem with the attestation key blob.
    TEE_ATT_UNSUPPORTED_ATT_KEY_ID = TEE_ATT_MK_ERROR(0x000b),         ///< Unsupported attestation key ID.
    TEE_ATT_UNSUPPORTED_LOADING_POLICY = TEE_ATT_MK_ERROR(0x000c),     ///< Unsupported enclave loading policy.
    TEE_ATT_INTERFACE_UNAVAILABLE = TEE_ATT_MK_ERROR(0x000d),          ///< Unable to load the QE enclave
    TEE_ATT_PLATFORM_LIB_UNAVAILABLE = TEE_ATT_MK_ERROR(0x000e),       ///< Unable to find the platform library with the dependent APIs.  Not fatal.
    TEE_ATT_ATT_KEY_NOT_INITIALIZED = TEE_ATT_MK_ERROR(0x000f),        ///< The attestation key doesn't exist or has not been certified.
    TEE_ATT_ATT_KEY_CERT_DATA_INVALID = TEE_ATT_MK_ERROR(0x0010),      ///< The certification data retrieved from the platform library is invalid.
    TEE_ATT_NO_PLATFORM_CERT_DATA = TEE_ATT_MK_ERROR(0x0011),          ///< The platform library doesn't have any platfrom cert data.
    TEE_ATT_OUT_OF_EPC = TEE_ATT_MK_ERROR(0x0012),                     ///< Not enough memory in the EPC to load the enclave.
    TEE_ATT_ERROR_REPORT = TEE_ATT_MK_ERROR(0x0013),                   ///< There was a problem verifying an SGX REPORT.
    TEE_ATT_ENCLAVE_LOST = TEE_ATT_MK_ERROR(0x0014),                   ///< Interfacing to the enclave failed due to a power transition.
    TEE_ATT_INVALID_REPORT = TEE_ATT_MK_ERROR(0x0015),                 ///< Error verifying the application enclave's report.
    TEE_ATT_ENCLAVE_LOAD_ERROR = TEE_ATT_MK_ERROR(0x0016),             ///< Unable to load the enclaves. Could be due to file I/O error, loading infrastructure error, or non-SGX capable system
    TEE_ATT_UNABLE_TO_GENERATE_QE_REPORT = TEE_ATT_MK_ERROR(0x0017),   ///< The QE was unable to generate its own report targeting the application enclave either
                                                                       ///< because the QE doesn't support this feature there is an enclave compatibility issue.
                                                                       ///< Please call again with the p_qe_report_info to NULL.
    TEE_ATT_KEY_CERTIFCATION_ERROR = TEE_ATT_MK_ERROR(0x0018),         ///< Caused when the provider library returns an invalid TCB (too high).
    TEE_ATT_NETWORK_ERROR = TEE_ATT_MK_ERROR(0x0019),                  ///< Network error when retrieving PCK certs
    TEE_ATT_MESSAGE_ERROR = TEE_ATT_MK_ERROR(0x001a),                  ///< Message error when retrieving PCK certs
    TEE_ATT_NO_QUOTE_COLLATERAL_DATA = TEE_ATT_MK_ERROR(0x001b),       ///< The platform does not have the quote verification collateral data available.
    TEE_ATT_QUOTE_CERTIFICATION_DATA_UNSUPPORTED = TEE_ATT_MK_ERROR(0x001c),
    TEE_ATT_QUOTE_FORMAT_UNSUPPORTED = TEE_ATT_MK_ERROR(0x001d),
    TEE_ATT_UNABLE_TO_GENERATE_REPORT = TEE_ATT_MK_ERROR(0x001e),
    TEE_ATT_QE_REPORT_INVALID_SIGNATURE = TEE_ATT_MK_ERROR(0x001f),
    TEE_ATT_QE_REPORT_UNSUPPORTED_FORMAT = TEE_ATT_MK_ERROR(0x0020),
    TEE_ATT_PCK_CERT_UNSUPPORTED_FORMAT = TEE_ATT_MK_ERROR(0x0021),
    TEE_ATT_PCK_CERT_CHAIN_ERROR = TEE_ATT_MK_ERROR(0x0022),
    TEE_ATT_TCBINFO_UNSUPPORTED_FORMAT = TEE_ATT_MK_ERROR(0x0023),
    TEE_ATT_TCBINFO_MISMATCH = TEE_ATT_MK_ERROR(0x0024),
    TEE_ATT_QEIDENTITY_UNSUPPORTED_FORMAT = TEE_ATT_MK_ERROR(0x0025),
    TEE_ATT_QEIDENTITY_MISMATCH = TEE_ATT_MK_ERROR(0x0026),
    TEE_ATT_TCB_OUT_OF_DATE = TEE_ATT_MK_ERROR(0x0027),
    TEE_ATT_TCB_OUT_OF_DATE_CONFIGURATION_NEEDED = TEE_ATT_MK_ERROR(0x0028),      ///< TCB out of date and Configuration needed
    TEE_ATT_SGX_ENCLAVE_IDENTITY_OUT_OF_DATE = TEE_ATT_MK_ERROR(0x0029),
    TEE_ATT_SGX_ENCLAVE_REPORT_ISVSVN_OUT_OF_DATE = TEE_ATT_MK_ERROR(0x002a),
    TEE_ATT_QE_IDENTITY_OUT_OF_DATE = TEE_ATT_MK_ERROR(0x002b),
    TEE_ATT_SGX_TCB_INFO_EXPIRED = TEE_ATT_MK_ERROR(0x002c),
    TEE_ATT_SGX_PCK_CERT_CHAIN_EXPIRED = TEE_ATT_MK_ERROR(0x002d),
    TEE_ATT_SGX_CRL_EXPIRED = TEE_ATT_MK_ERROR(0x002e),
    TEE_ATT_SGX_SIGNING_CERT_CHAIN_EXPIRED = TEE_ATT_MK_ERROR(0x002f),
    TEE_ATT_SGX_ENCLAVE_IDENTITY_EXPIRED = TEE_ATT_MK_ERROR(0x0030),
    TEE_ATT_PCK_REVOKED = TEE_ATT_MK_ERROR(0x0031),
    TEE_ATT_TCB_REVOKED = TEE_ATT_MK_ERROR(0x0032),
    TEE_ATT_TCB_CONFIGURATION_NEEDED = TEE_ATT_MK_ERROR(0x0033),
    TEE_ATT_UNABLE_TO_GET_COLLATERAL = TEE_ATT_MK_ERROR(0x0034),
    TEE_ATT_ERROR_INVALID_PRIVILEGE = TEE_ATT_MK_ERROR(0x0035),        ///< No enough privilege to perform the operation
    TEE_ATT_NO_QVE_IDENTITY_DATA = TEE_ATT_MK_ERROR(0x0037),           ///< The platform does not have the QVE identity data available.
    TEE_ATT_CRL_UNSUPPORTED_FORMAT = TEE_ATT_MK_ERROR(0x0038),
    TEE_ATT_QEIDENTITY_CHAIN_ERROR = TEE_ATT_MK_ERROR(0x0039),
    TEE_ATT_TCBINFO_CHAIN_ERROR = TEE_ATT_MK_ERROR(0x003a),
    TEE_ATT_ERROR_QVL_QVE_MISMATCH = TEE_ATT_MK_ERROR(0x003b),          ///< QvE returned supplemental data version mismatched between QVL and QvE
    TEE_ATT_TCB_SW_HARDENING_NEEDED = TEE_ATT_MK_ERROR(0x003c),         ///< TCB up to date but SW Hardening needed
    TEE_ATT_TCB_CONFIGURATION_AND_SW_HARDENING_NEEDED = TEE_ATT_MK_ERROR(0x003d),        ///< TCB up to date but Configuration and SW Hardening needed

    TEE_ATT_UNSUPPORTED_MODE = TEE_ATT_MK_ERROR(0x003e),

    TEE_ATT_NO_DEVICE = TEE_ATT_MK_ERROR(0x003f),
    TEE_ATT_SERVICE_UNAVAILABLE = TEE_ATT_MK_ERROR(0x0040),
    TEE_ATT_NETWORK_FAILURE = TEE_ATT_MK_ERROR(0x0041),
    TEE_ATT_SERVICE_TIMEOUT = TEE_ATT_MK_ERROR(0x0042),
    TEE_ATT_ERROR_BUSY = TEE_ATT_MK_ERROR(0x0043),

    TEE_ATT_UNKNOWN_MESSAGE_RESPONSE  = TEE_ATT_MK_ERROR(0x0044),      /// Unexpected error from the cache service
    TEE_ATT_PERSISTENT_STORAGE_ERROR  = TEE_ATT_MK_ERROR(0x0045),      /// Error storing the retrieved cached data in persistent memory
    TEE_ATT_ERROR_MESSAGE_PARSING_ERROR   = TEE_ATT_MK_ERROR(0x0046),  /// Message parsing error
    TEE_ATT_PLATFORM_UNKNOWN  = TEE_ATT_MK_ERROR(0x0047),              /// Platform was not found in the cache
    TEE_ATT_UNKNOWN_API_VERSION  = TEE_ATT_MK_ERROR(0x0048),           /// The current PCS API version configured is unknown
    TEE_ATT_CERTS_UNAVAILABLE  = TEE_ATT_MK_ERROR(0x0049),             /// Certificates are not available for this platform

    TEE_ATT_QVEIDENTITY_MISMATCH = TEE_ATT_MK_ERROR(0x0050),          ///< QvE Identity is NOT match to Intel signed QvE identity
    TEE_ATT_QVE_OUT_OF_DATE = TEE_ATT_MK_ERROR(0x0051),               ///< QvE ISVSVN is smaller then the ISVSVN threshold
    TEE_ATT_PSW_NOT_AVAILABLE = TEE_ATT_MK_ERROR(0x0052),             ///< SGX PSW library cannot be loaded, could be due to file I/O error
    TEE_ATT_COLLATERAL_VERSION_NOT_SUPPORTED = TEE_ATT_MK_ERROR(0x0053),  ///< SGX quote verification collateral version not supported by QVL/QvE
    TEE_ATT_TDX_MODULE_MISMATCH = TEE_ATT_MK_ERROR(0x0060),            ///< TDX SEAM module identity is NOT match to Intel signed TDX SEAM module

    TEE_ATT_QEIDENTITY_NOT_FOUND = TEE_ATT_MK_ERROR(0x0061),            ///< QE identity was not found
    TEE_ATT_TCBINFO_NOT_FOUND = TEE_ATT_MK_ERROR(0x0062),               ///< TCB Info was not found
    TEE_ATT_INTERNAL_SERVER_ERROR = TEE_ATT_MK_ERROR(0x0063),           ///< Internal server error

    TEE_ATT_SUPPLEMENTAL_DATA_VERSION_NOT_SUPPORTED = TEE_ATT_MK_ERROR(0x0064),       ///< The supplemental data version is not supported

    TEE_ATT_ROOT_CA_UNTRUSTED = TEE_ATT_MK_ERROR(0x0065),               ///< The certificate used to establish SSL session is untrusted
    TEE_ATT_TCB_NOT_SUPPORTED = TEE_ATT_MK_ERROR(0x0066),               ///< Current TCB level cannot be found in platform/enclave TCB info 

    TEE_ATT_CONFIG_INVALID_JSON = TEE_ATT_MK_ERROR(0x0067),             ///< The QPL's config file is in JSON format but has a format error

    TEE_ATT_ERROR_MAX = TEE_ATT_MK_ERROR(0x00FF),                       ///< Indicate max error to allow better translation.

} tee_att_error_t;

typedef struct tee_att_config_t tee_att_config_t;

typedef enum
{
    TEE_ATT_TDQE,
    TEE_ATT_PCE,
    TEE_ATT_QPL,
    TEE_ATT_IDE,
} tee_att_ae_type_t;



#pragma pack(push, 1)

typedef struct _tee_platform_info_t {
    sgx_key_128bit_t platform_id;
    sgx_cpu_svn_t cpu_svn;
    sgx_isv_svn_t tdqe_isv_svn;
    sgx_isv_svn_t pce_isv_svn;
} tee_platform_info_t;

#pragma pack(pop)


#if defined(__cplusplus)
extern "C" {
#endif

/**
 * The application calls this API to selected a platform's attestation key id and alloc a context to be used
 * during quote generation flow. The application need to call tee_att_free_context to release the context after
 * it is not used anymore.
 *
 * @param p_att_key_id The selected att_key_id from the quote verifier's list.  It includes the QE identity as
 *                     well as the attestation key's algorithm type. It can be NULL to use default list.
 * @param p_path A full path of TDQE. It can be NULL to use default path.
 * @param pp_context Allocated context that contains information during quote generation flow. It cannot be NULL.
 * @return TEE_ATT_SUCCESS Successfully created the context using the attestation key.
 * @return TEE_ATT_UNSUPPORTED_ATT_KEY_ID p_att_key_id is not valid.
 * @return TEE_ATT_ERROR_INVALID_PARAMETER pp_context is NULL. Or p_qe_path is not valid.
 *
 */
tee_att_error_t tee_att_create_context(const tee_att_att_key_id_t* p_att_key_id,
    const char* p_qe_path,
    tee_att_config_t** pp_context);

/**
 * The application calls this API to release the context.
 *
 * @param p_context The context that contains information during quote generation flow.
 * @return TEE_ATT_SUCCESS Successfully released the context.
 * @return TEE_ATT_ERROR_INVALID_PARAMETER p_context is NULL.
 *
 */
tee_att_error_t tee_att_free_context(tee_att_config_t* p_context);

/**
 * The application calls this API to request the selected platform's attestation key owner to generate or obtain
 * the attestation key.  Once called, the QE that owns the attestation key described by the inputted attestation
 * key id will do what is required to get this platform's attestation including getting any certification data
 * required from the PCE.  Depending on the type of attestation key and the attestation key owner, this API will
 * return the same attestation key public ID or generate a new one.  The caller can request that the attestation
 * key owner "refresh" the key.  This will cause the owner to either re-get the key or generate a new one.  The
 * platform's attestation key owner is expected to store the key in persistent memory and use it in the
 * subsequent quote generation APIs described below.
 *
 * In an environment where attestation key provisioning and certification needs to take place during a platform
 * deployment phase, an application can generate the attestation key, certify it with the PCK Cert and register
 * it with the attestation owners cloud infrastructure.  That way, the key is available during the run time
 * phase to generate code without requiring re-certification.
 *
 * The QE's target info is also returned by this API that will allow the application's enclave to generate a
 * REPORT that the attestation key owner's QE can verify using local REPORT-based attestation when generating a
 * quote.
 *
 * In order to allow the application to allocate the public key id buffer first, the application can call this
 * function with the p_pub_key_id set to NULL and the p_pub_key_id_size to a valid size_t pointer.  In this
 * case, the function will return the required buffer size to contain the p_pub_key_id_size and ignore the other
 * parameters.  The application can then call this API again with the correct p_pub_key_size and the pointer to
 * the allocated buffer in p_pub_key_id.
 *
 * @param p_context The context that contains information during quote generation flow.
 * @param p_qe_target_info Pointer to QE's target info required by the application to generate an enclave REPORT
 *                         targeting the selected QE.  Must not be NULL when p_pub_key_id is not NULL.
 * @param refresh_att_key A flag indicating the attestation key owner should re-generated and certify or
 *                        otherwise attempt to re-provision the attestation key.  For example, for ECDSDA, the
 *                        platform will generate a new key and request the PCE to recertify it.  For EPID, the
 *                        platform will attempt to re-provision the EPID key.  The behavior is dependent on the
 *                        key type and the key owner, but it should make an attempt to refresh the key typically
 *                        to update the key to the current platform's TCB.
 * @param p_pub_key_id_size This parameter can be used in 2 ways.  When p_pub_key_id is NULL, the API will
 *                          return the buffer size required to hold the attestation's public key ID.  The
 *                          application can then allocate the buffer and call it again with p_pub_key_id not set
 *                          to NULL and the other parameters valid.  If p_pub_key_id is not NULL, p_pub_key_size
 *                          must be large enough to hold the return attestation's public key ID.  Must not be
 *                          NULL.
 * @param p_pub_key_id This parameter can be used in 2 ways. When it is passed in as NULL and p_pub_key_id_size
 *                     is not NULL, the API will return the buffer size required to hold the attestation's
 *                     public key ID.  The other parameters will be ignored.  When it is not NULL, it must point
 *                     to a buffer which is at least a long as the value passed in by p_pub_key_id.  Can either
 *                     be NULL or point to the correct buffer.his will point to the buffer that will contain the
 *                     attestation key's public identifier. If first called with a NULL pointer, the API will
 *                     return the required length of the buffer in p_pub_key_id_size.
 * @return TEE_ATT_SUCCESS Successfully selected an attestation key.  Either returns the required attestation's
 *                         public key ID size in p_pub_key_id_size when p_pub_key_id is passed in as NULL.  When
 *                         p_pub_key_id is not NULL, p_qe_target_info will contain the attestation key's QE
 *                         target info for REPORT generation and p_pub_key_id will contain the attestation's
 *                         public key ID.
 * @return TEE_ATT_ERROR_INVALID_PARAMETER Invalid parameter if p_pub_key_id_size is NULL.  If p_pub_key_size is
 *                                         not NULL, the other parameters must be valid.
 * @return TEE_ATT_ERROR_OUT_OF_MEMORY There is not enough EPC memory to load one of the Architecture Enclaves
 *                                     needed to complete this operation.
 * @return TEE_ATT_ENCLAVE_LOST Enclave lost after power transition or used in child process created by
 *                              linux:fork().
 * @return TEE_ATT_ENCLAVE_LOAD_ERROR Unable to load the enclaves required to initialize the attestation key.
 *                                    Could be due to file I/O error, loading infrastructure error or insufficient
 *                                    enclave memory.
 * @return TEE_ATT_ERROR_INVALID_PRIVILEGE No enough privilege to perform the operation.
 * @return TEE_ATT_ERROR_UNEXPECTED Unexpected internal error.
 *
 */
tee_att_error_t tee_att_init_quote(const tee_att_config_t* p_context,
    sgx_target_info_t* p_qe_target_info,
    bool refresh_att_key,
    size_t* p_pub_key_id_size,
    uint8_t* p_pub_key_id);


/**
 * The application needs to call this function before generating a quote.  The quote size is variable
 * depending on the type of attestation key selected and other platform or key data required to generate the
 * quote.  Once the application calls this API, it will use the returned p_quote_size to allocate the buffer
 * required to hold the generated quote.  A pointer to this buffer is provided to the tee_att_get_quote() API.
 *
 * If the key is not available, this API may return an error (TEE_ATT_ATT_KEY_NOT_INITIALIZED) depending on
 * the algorithm.  In this case, the caller must call sgx_ql_init_quote() to re-generate and certify the
 * attestation key.
 *
 * @param p_context The context that contains information during quote generation flow.
 * @param p_quote_size Pointer to the location where the required quote buffer size will be returned. Must
 *                     not be NULL.
 * @return TEE_ATT_SUCCESS Successfully calculated the required quote size. The required size in bytes is
 *                         returned in the memory pointed to by p_quote_size.
 * @return TEE_ATT_ATT_KEY_NOT_INITIALIZED The Attestaion key has not been generated, certified or requires
 *                                         recertification yet. Need to call InitQuote first/again to get attestaion
 *                                         key regenerated/receritifed.
 * @return TEE_ATT_ATT_KEY_CERT_DATA_INVALID Quote certification data from the platform library is invalid.
 * @return TEE_ATT_ERROR_INVALID_PARAMETER Invalid parameter if p_quote_size is NULL. Or p_context is not valid.
 * @return TEE_ATT_ERROR_OUT_OF_MEMORY There is not enough EPC memory to load one of the Architecture Enclaves
 *                                     needed to complete this operation.
 * @return TEE_ATT_ENCLAVE_LOST Enclave lost after power transition or used in child process created by
 *                              linux:fork().
 * @return TEE_ATT_ENCLAVE_LOAD_ERROR Unable to load the enclaves required to initialize the attestation key.
 *                                    Could be due to file I/O error, loading infrastructure error or insufficient 
 *                                    enclave memory.
 * @return TEE_ATT_ERROR_INVALID_PRIVILEGE No enough privilege to perform the operation.
 * @return TEE_ATT_ERROR_UNEXPECTED Unexpected internal error.
 */
tee_att_error_t tee_att_get_quote_size(const tee_att_config_t* p_context,
    uint32_t* p_quote_size);


/**
 * The function will take the application enclave's REPORT that will be converted into a quote after the QE verifies
 * the REPORT.  Once verified it will sign it with platform's attestation key matching the selected attestation key
 * ID.  If the key is not available, this API may return an error (TEE_ATT_ATT_KEY_NOT_INITIALIZED) depending on the
 * algorithm.  In this case, the caller must call tee_att_init_quote() to get the library to
 * re-generate/re-certify the attestation key.
 *
 * @param p_context The context that contains information during quote generation flow.
 * @param p_report Pointer to the application enclave's REPORT that needs the quote.  The report needs to be generated
 *                 using the QE's target info reurned by the tee_att_init_quote() API.  Must not be NULL.
 * @param report_size size of the application enclave's REPORT.
 * @param p_qe_report_info Pointer to a data structure that will contain the information required for the QE to generate
 *                         a REPORT that can be verified by the application enclave.  The inputted data structure
 *                         contains the application's TARGET_INFO, a nonce and a buffer to hold the generated report.
 *                         The QE Report will be generated using the target information and the QE's REPORT.ReportData =
 *                         SHA256(*p_nonce||*p_quote)||32-0x00's. This parameter is used when the application wants to
 *                         verify the QE's REPORT to provide earlier detection that the QE is not being spoofed by
 *                         untrusted code.  A spoofed QE will ultimately be rejected by the remote verifier. This
 *                         parameter is optional and will be ignored when NULL.
 * @param quote_size Size of the buffer pointed to by p_quote (in bytes).
 * @param p_quote Pointer to the buffer that will contain the generated quote.  Must not be NULL.
 * @return TEE_ATT_SUCCESS Successfully created the quote.
 * @return TEE_ATT_ERROR_INVALID_PARAMETER One of the parameters is not valid.
 * @return TEE_ATT_ATT_KEY_NOT_INITIALIZED The Attestaion key has not been generated, certified or requires
 *                                         recertification yet. Need to call InitQuote first/again to get attestaion
 *                                         key regenerated/receritifed.
 * @return TEE_ATT_ATT_KEY_CERT_DATA_INVALID Quote certification data from the platform library is invalid.
 * @return TEE_ATT_ERROR_OUT_OF_MEMORY There is not enough EPC memory to load one of the Architecture Enclaves
 *                                     needed to complete this operation.
 * @return TEE_ATT_ENCLAVE_LOST Enclave lost after power transition or used in child process created by
 *                              linux:fork().
 * @return TEE_ATT_ENCLAVE_LOAD_ERROR Unable to load the enclaves required to initialize the attestation key.
 *                                    Could be due to file I/O error, loading infrastructure error or insufficient 
 *                                    enclave memory.
 * @return TEE_ATT_ERROR_INVALID_PRIVILEGE No enough privilege to perform the operation.
 * @return TEE_ATT_ERROR_UNEXPECTED Unexpected internal error.
 */
tee_att_error_t tee_att_get_quote(const tee_att_config_t* p_context,
    const uint8_t* p_report,
    uint32_t report_size,
    sgx_qe_report_info_t* p_qe_report_info,
    uint8_t* p_quote,
    uint32_t quote_size);

/**
 * The application can call this function to get the selected att_key_id.
 *
 * @param p_context The context that contains information during quote generation flow.
 * @param p_att_key_id The selected att_key_id from the quote verifier's list. It cannot be NULL.
 * @return TEE_ATT_SUCCESS Successfully created the quote.
 * @return TEE_ATT_ERROR_INVALID_PARAMETER One of the parameters is not valid.
 * @return TEE_ATT_ERROR_UNEXPECTED Unexpected internal error.
 */
tee_att_error_t tee_att_get_keyid(const tee_att_config_t* p_context,
    tee_att_att_key_id_t* p_att_key_id);

/**
 * The application can call this function to get the platform info.
 *
 * @param p_context The context that contains information during quote generation flow.
 * @param p_platform_info Pointer to returned information of current platform. It cannot be NULL.
 * @return TEE_ATT_SUCCESS Successfully retrived platform info.
 * @return TEE_ATT_ATT_KEY_NOT_INITIALIZED The Attestaion key has not been generated, certified or requires
 *                                         recertification yet. Need to call InitQuote first/again to get attestaion
 *                                         key regenerated/receritifed.
 * @return TEE_ATT_ERROR_INVALID_PARAMETER Invalid parameter if p_platform_info is NULL. Or p_context is not valid.
 * @return TEE_ATT_ERROR_OUT_OF_MEMORY There is not enough EPC memory to load one of the Architecture Enclaves
 *                                     needed to complete this operation.
 * @return TEE_ATT_ENCLAVE_LOST Enclave lost after power transition or used in child process created by
 *                              linux:fork().
 * @return TEE_ATT_ENCLAVE_LOAD_ERROR Unable to load the enclaves required to initialize the attestation key.
 *                                    Could be due to file I/O error, loading infrastructure error or insufficient
 *                                    enclave memory.
 * @return TEE_ATT_ERROR_INVALID_PRIVILEGE No enough privilege to perform the operation.
 * @return TEE_ATT_ERROR_UNEXPECTED Unexpected internal error.
 */
tee_att_error_t tee_att_get_platform_info(const tee_att_config_t* p_context,
    tee_platform_info_t* p_platform_info);

#ifndef _MSC_VER
/**
 * This API can be used to set the full path of TDQE, IDE, PCE and QPL library.
 *
 * The function takes the enum and the corresponding full path.
 *
 * @param p_context The context that contains information during quote generation flow.
 * @param type Specify the full path of which binary is going to be changed.
 * @param p_path It should be a valid path.
 * @return TEE_ATT_SUCCESS  Successfully set the full path.
 * @return TEE_ATT_UNSUPPORTED_MODE This function is called on Windows.
 * @return TEE_ATT_ERROR_INVALID_PARAMETER p_path is not a valid full path or the path is too long.
 * @return TEE_ATT_ERROR_UNEXPECTED An unexpected internal error occurred.
 *
 */
tee_att_error_t tee_att_set_path(const tee_att_config_t* p_context,
    tee_att_ae_type_t type,
    const char* p_path);
#endif
#if defined(__cplusplus)
}
#endif


#endif

